﻿using System;
using System.ComponentModel;
using Loki;
using Loki.Commands;
using Loki.UI;
using Luna.Model;
using Luna.Model.Accounting;
using Luna.Model.Project;
using Luna.UI.Accounting;
using Luna.UI.Project;
using Luna.UI.Users;

namespace Luna.UI
{
    public class MainViewModel : ContainerViewModel<LunaModel>
    {
        public MainViewModel()
        {
            Navigation = new NavigationModel();
            MainMenu = new MainMenuModel();

            Init += MainViewModel_Init;
            Load += MainViewModel_Load;
        }

        private void MainViewModel_Load(object P_Sender, System.EventArgs e)
        {
            CurrentUser = ApplicationModel.CurrentUser.FullName;
        }

        private void MainViewModel_Init(object P_Sender, System.EventArgs e)
        {
            // Account
            Commands.Handle(LunaCommands.Navigation.Account.ADMIN, Account_Operations_Execute);
            Commands.Handle(NavigationCommands.ACCOUNT_OPERATION_CATEGORIES, Account_Categories_Execute);
            Commands.Handle(LunaCommands.Application.LOAD, Account_Load_CanExecute, Account_Load_Execute);
            Commands.Handle(LunaCommands.Navigation.Account.REPORTING, Account_Reporting_Execute);

            // Project
            Commands.Handle(LunaCommands.Navigation.Project.LIST, Project_List_Execute);
            Commands.Handle(LunaCommands.Application.LOAD, Project_Load_CanExecute, Project_Load_Execute);
            Commands.Handle(LunaCommands.Navigation.Project.REPORTING, Project_Reporting_Execute);

            // Users
            Commands.Handle(LunaCommands.Navigation.User.ADMIN, User_List_Execute);

            ActivateOrAdd<AccountingCategoryListViewModel>(null, s => s.DisplayName = "Categories");
            ActivateOrAdd<AccountListViewModel>(null, s => s.DisplayName = "Liste des comptes");
        }

        public MainMenuModel MainMenu { get; private set; }

        public NavigationModel Navigation { get; private set; }

        #region Properties

        #region  CurrentUser
        private static PropertyChangedEventArgs _CurrentUserChangeArgs = ObservableHelper.CreateArgs<MainViewModel>(x => x.CurrentUser);

        private string _CurrentUser;

        public string CurrentUser
        {
            get
            {
                return _CurrentUser;
            }

            set
            {
                if (value != _CurrentUser)
                {
                    _CurrentUser = value;
                    NotifyChanged(_CurrentUserChangeArgs);
                }
            }
        }
        #endregion

        #endregion

        #region Navigation Handlers

        #region Application.Load - Accounts
        public void Account_Load_CanExecute(object P_Sender, CanExecuteCommandEventArgs e)
        {
            e.CanExecute |= e.Parameter is IAccount || e.Parameter is IEditableAccount;
        }

        public void Account_Load_Execute(object P_Sender, CommandEventArgs e)
        {
            IEditableAccount L_EditAccount = null;
            IAccount L_Account = e.Parameter as IAccount;
            if (L_EditAccount == null && L_Account != null)
            {
                L_EditAccount = L_Account.EditableVersion;
            }

            if (L_EditAccount != null)
            {
                ActivateOrAdd<AccountDetailViewModel>(vm => vm.CurrentAccount.ID == L_EditAccount.ID, vm => vm.CurrentAccount = L_EditAccount);
            }
            else
            {
                Log.ErrorFormat(Messages.LogMessages.INVALID_ACCOUNT, e.Parameter);
            }
        }
        #endregion

        #region Navigation.Account.Operations
        public void Account_Operations_Execute(object P_Sender, CommandEventArgs e)
        {
            ActivateOrAdd<AccountListViewModel>();
        }
        #endregion

        #region Navigation.Account.Categories
        public void Account_Categories_Execute(object P_Sender, CommandEventArgs e)
        {
            ActivateOrAdd<AccountingCategoryListViewModel>();
        }
        #endregion

        #region Navigation.Account.Reporting
        public void Account_Reporting_Execute(object P_Sender, CommandEventArgs e)
        {
            ActivateOrAdd<AccountingGraphViewModel>();
        }
        #endregion

        #region Navigation.Project.List
        public void Project_List_Execute(object P_Sender, CommandEventArgs e)
        {
            ActivateOrAdd<ProjectListViewModel>();
        }
        #endregion

        #region Application.Load - Projects
        public void Project_Load_CanExecute(object P_Sender, CanExecuteCommandEventArgs e)
        {
            e.CanExecute |= e.Parameter is IProject || e.Parameter is IEditableProject;
        }

        public void Project_Load_Execute(object P_Sender, CommandEventArgs e)
        {
            IEditableProject L_EditProject = null;
            IProject L_Project = e.Parameter as IProject;
            if (L_EditProject == null && L_Project != null)
            {
                L_EditProject = L_Project.EditableVersion;
            }

            if (L_EditProject != null)
            {
                ActivateOrAdd<ProjectDetailViewModel>(vm => vm.CurrentProject.ID == L_EditProject.ID, vm => vm.CurrentProject = L_EditProject);
            }
            else
            {
                Log.ErrorFormat(Messages.LogMessages.INVALID_PROJECT, e.Parameter);
            }
        }
        #endregion

        #region Navigation.Project.Reporting
        public void Project_Reporting_Execute(object P_Sender, CommandEventArgs e)
        {
            ActivateOrAdd<ProjectGraphViewModel>();
        }
        #endregion

        #region Navigation.User.List
        public void User_List_Execute(object P_Sender, CommandEventArgs e)
        {
            ActivateOrAdd<UserListViewModel>();
        }
        #endregion

        #endregion

        private void MainViewModel_Initialize(object P_Sender, EventArgs e)
        {
            CurrentUser = ApplicationModel.CurrentUser.FullName;
        }
    }
}
